package org.example.quartz.task;

import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.UtilService;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class XZDeptQuartz implements QuartzTaskJob {


    Map<String, Object> gsMap = DataSourceUtil.getGS();
    //全局接口配置
    String IP = (String) gsMap.get("IP");
    String PORT = (String) gsMap.get("PORT");
    String ECC = (String) gsMap.get("ECC");
    String Bearer = (String) gsMap.get("Bearer");

    //日志
    LogService loginfo = SpringUtil.getBean(LogService.class);
    //orgService
    OrgService orgService = SpringUtil.getBean(OrgService.class);
    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);

    /**
     * 核算部门接口
     * 接口地址：GSCloud文档3.1、3.2
     * 行政部门
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncZzjg
     * 核算部门
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncHsbm
     **/
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        try{
        //传入变量 lastTime 最后抓取时间
        //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
        //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
        //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
        //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
        //查询脚本
        /**
         * SELECT
         * DEPT.CODE,
         * DEPT.NAME,
         * (CASE WHEN FADEPT.code IS NULL THEN ORG.CODE ELSE FADEPT.code END) as PARENTCODE,
         * 'Department' as ORGTYPE,
         * DEPT.TEL AS TEL
         * FROM
         * ORG_DEPT DEPT
         * LEFT JOIN ORG_DEPT FADEPT ON DEPT.pk_fatherorg = FADEPT.pk_dept
         * LEFT JOIN ORG_ORGS ORG ON DEPT.pk_org =ORG.PK_ORG
         * WHERE
         * DEPT.DR =0
         * AND
         * DEPT.TS > '2024-01-01 00:00:000'
         * */
        String methodName = "XZDeptQuartz";
        //JdbcTemplate jdbcTemplate = new JdbcTemplate();
        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
        //1、查询时间
        String ts = utilService.getTs(methodName, jdbcTemplate);
        String orgStr = utilService.getGSOrgStr(jdbcTemplate);
        //2、根据时间查询数据集 (停用和删除的过滤掉，暂不考虑，线下处理)
        String selectSQL = "SELECT \n" +
                "DEPT.PK_DEPT AS YYID,\n" +
                "DEPT.CODE AS CODE,\n" +
                "DEPT.NAME,\n" +
                "(CASE WHEN FADEPT.code IS NULL THEN ORG.CODE ELSE FADEPT.CODE END) as PARENTCODE,\n" +
                "ORG.CODE AS ORGCODE,\n" +
                "'Department' as ORGTYPE,\n" +
                "(CASE WHEN FADEPT.code IS NULL THEN '是' ELSE '否' END) as ISORG,\n" +
                "DEPT.TEL AS TEL,\n" +
                "DEPT.TS AS TS\n" +
                "FROM \n" +
                "ORG_DEPT DEPT\n" +
                "LEFT JOIN ORG_DEPT FADEPT ON DEPT.pk_fatherorg = FADEPT.pk_dept\n" +
                "LEFT JOIN ORG_ORGS ORG ON DEPT.pk_org =ORG.PK_ORG \n" +
                "WHERE \n" +
                "DEPT.DR =0\n" +
                "AND\n" +
                "DEPT.ENABLESTATE =2\n" +
                "and \n" +
                "org.code in ("+orgStr+")\n" +
                "AND\n" +
                "DEPT.TS > '"+ts+"'\n" +
                "ORDER BY LENGTH(CODE) ASC ,TS ASC\n";
        //查询数据，根据数据结果推送给GS浪潮
        Session oracleSession = DataSourceUtil.getOracleSession();
        List<Entity> query = oracleSession.query(selectSQL);
        //拼装数据，推送给浪潮
        if(query.size()>0){
            for (Map<String, Object> gSmap : query) {
                String yyid = (String) gSmap.get("YYID");
                String gsCode = "";
                //转换ORGCODE
                String orgCode = orgService.selectGsCode((String) gSmap.get("ORGCODE"), jdbcTemplate);
                //根据组织编码，查询出账套信息，如果有多个账套，轮询进行处理
                List<Map<String, Object>> yyztCodeMap = orgService.selectZtCode((String) gSmap.get("ORGCODE"), jdbcTemplate);
                //账簿轮询
                for (int x = 0; x < yyztCodeMap.size(); x++){
                    String yyztCode = (String) yyztCodeMap.get(x).get("yyztCode");
                if (gSmap.get("ISORG").equals("是")) {
                    gsCode = orgService.selectGsCode((String) gSmap.get("PARENTCODE"), jdbcTemplate);
                } else {
                    gsCode = yyztCode+ gSmap.get("PARENTCODE");
                }
                String GsxzJson =
                        "{\n" +
                                "    \"CODE\":\""+ yyztCode + gSmap.get("CODE") + "\",\n" +
                                "    \"NAME\":\"" + gSmap.get("NAME") +yyztCode+ "\",\n" +
                                "    \"PARENTCODE\":\"" + gsCode + "\",\n" +
                                "    \"ORGCODE\":\"" + orgCode + "\",\n" +
                                "    \"ORGTYPE\":\"Department\",\n" +
                                "    \"TEL\":\"" + gSmap.get("TEL") + "\"\n" +
                                "}";
                //调用GS接口，推送给GS浪潮，获取返回值;
                //1、推送行政部门档案
                String gsUrl = "https://" + IP + ":" + PORT + "/api/jg/syncbddata/v1.0/bdsyncinterface/syncZzjg";
                String returnMSG = HttpRequest.post(gsUrl)
                        .header("Content-Type", "application/json")
                        .header("Accept-Language", "zh-CHS")
                        .header("X-ECC-Current-Tenant", ECC)
                        .header("Authorization", Bearer).timeout(200000)
                        .body(GsxzJson).execute().body();
                if (!returnMSG.isEmpty()) {
                    String logInsert = "";
                    JSONObject returnObj = JSONObject.parseObject(returnMSG);
                    //成功
                    if (returnObj.get("code").equals("0") ) {
                        //写入日志表
                        int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "成功", GsxzJson, returnMSG, "", yyid, gsUrl, (String) gSmap.get("TS"));
                        if (loginsert > 0) {
                          //  System.out.println("日志写入成功！！");
                        } else {
                            System.out.println("日志写入失败！！");
                        }
                        //失败
                    } else if (returnObj.get("code").equals("1") ) {
                        //写入日志表
                        int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "失败", GsxzJson, returnMSG, "", yyid, gsUrl, (String) gSmap.get("TS"));
                        if (loginsert > 0) {
                          //  System.out.println("日志写入成功！！");
                        } else {
                            System.out.println("日志写入失败！！");
                        }
                    }else if(returnObj.get("code")==null && ("").equals(returnObj.get("code"))){
                        //写入日志表
                        int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsxzJson, returnMSG, "",  (String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                        if (loginsert > 0) {
                          //  System.out.println("日志写入成功！！");
                        } else {
                            System.out.println("日志写入失败！！");
                        }
                    }
                    }
                }
            }
        }else{
            System.out.println("暂无新数据推送");
        }

    }catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        //关闭链接
        DataSourceUtil.closeOracleSession();
        DataSourceUtil.closeMysqlSession();
    }
}


}
